﻿#define _CRT_SECURE_NO_WARNINGS
#include "ThreadCache.h"
// 申请内存对象 
void* ThreadCache::Allocate(size_t sz)
{
	assert(sz <= MAX_BYTE);
	size_t alignNum = SizeClass::RoundUp(sz);//计算对齐后的大小
	void* obj;
	int index = SizeClass::Index(sz);
	if (_freeList[index].Empty())
	{
		obj = FetchFromCentralCache(index, alignNum);
	}
	else
	{
		obj = _freeList[index].pop();
	}
	return obj;
}
//释放内存对象
void ThreadCache::Deallocate(void* ptr, size_t sz)
{
	assert(ptr);
	assert(sz <= MAX_BYTE);
	int index = SizeClass::Index(sz);
	_freeList[index].push(ptr);

	if (_freeList[index].Size() >= _freeList[index].MaxSize())
	{
		ListTooLong(_freeList[index], sz);
	}
}

// 从中⼼缓存获取对象 
void* ThreadCache::FetchFromCentralCache(size_t index, size_t alignNum)
{
	assert(index < NFREELIST);
	assert(alignNum <= MAX_BYTE);
	//去CentralCache要几个对象——慢开始的反馈调节算法
	size_t batchNum = min(SizeClass::NumMoveSize(alignNum), _freeList[index].MaxSize());
	if (batchNum == _freeList[index].MaxSize())
	{
		_freeList[index].MaxSize() += 1;
	}
	
	void* begin = nullptr;
	void* end = nullptr;
	size_t actualNum = CentralCache::GetInstance().FetchRangeObj(begin, end, batchNum, alignNum);//实际上CentralCache给了几个对象
	assert(begin || end);
	assert(actualNum >= 1);//最少要获取到一个对象
	if (actualNum == 1)
	{
		return begin;
	}
	else
	{
		_freeList[index].pushRange(Next(begin), end, actualNum - 1);
		return begin;
	}
}

void ThreadCache::ListTooLong(FreeList& freeList, size_t sz)
{
	void* begin = nullptr;
	void* end = nullptr;
	freeList.popRange(begin, end, freeList.MaxSize());
	CentralCache::GetInstance().ReleaseListToSpans(begin, sz);
}
